﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Linq;
using System.Linq;
using System.Web;
using FacturIT.BLL.Model.Helper;
using FacturIT.BLL.Model.User;

namespace FacturIT.Service.Repositories
{
    public class UserRepository : IRepository<BLL.Model.User.User, int>
    {
        public UserRepository()
        {
            DB = new UserManagementDataContext(ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["DatabaseToUse"]].ConnectionString);
        }

        protected Table<BLL.Model.User.User> DT
        {
            get { return ((UserManagementDataContext)base.DB).Users; }
        }

        public override BLL.Model.User.User Read(int id)
        {
            BLL.Model.User.User user = ReadByID(id);
            return user == null ? null : user;
        }
        public BLL.Model.User.User Read(string name)
        {
            return (from user in DT
                    where (user.Firstname.ToLower() + " " + user.Lastname.ToLower()).Equals(name.ToLower()) || (user.Lastname.ToLower() + " " + user.Firstname.ToLower()).Equals(name.ToLower())
                    select user).FirstOrDefault();
        }

        public override IEnumerable<BLL.Model.User.User> ReadAll()
        {
            return from user in DT
                   orderby user.Lastname
                   select user;
        }

        public override IEnumerable<BLL.Model.User.User> ReadAll(params int[] ids)
        {
            return from user in DT
                   where ids.Contains(user.UserID)
                   select user;
        }
        internal IEnumerable<BLL.Model.User.User> ReadAll(List<int> assetIDs)
        {
            return from user in DT
                   where assetIDs.Contains(user.UserID)
                   select user;
        }

        internal BLL.Model.User.User ReadUserByUserName(string username)
        {
            return (from user in DT
                    where username.ToLower().Equals(user.Username.ToLower())
                    select user).FirstOrDefault();
        }

        internal IEnumerable<BLL.Model.User.User> ReadAllUsersByLastName(string username)
        {
            return from user in DT
                   where user.Username.ToLower().Equals(username.ToLower())
                   orderby user.Lastname ascending, user.Firstname ascending, user.Username ascending
                   select user;
        }

        public override BLL.Model.User.User Add(BLL.Model.User.User t)
        {
            DT.InsertOnSubmit(t);
            SaveChanges();
            return ReadByID(t.UserID);
        }

        public override bool Delete(BLL.Model.User.User t)
        {
            DT.DeleteOnSubmit(t);
            SaveChanges();
            return !Exists(t.UserID);
        }

        public override BLL.Model.User.User Update(BLL.Model.User.User t)
        {
            UpdateObject(ReadByID(t.UserID), t, false);
            SaveChanges();
            return ReadByID(t.UserID);
        }

        public override BLL.Model.User.User Duplicate(BLL.Model.User.User t)
        {
            return Add(Create(t.Lastname, t.Firstname, t.Phonenumber, t.Street, t.PostalCode, t.City, t.Country, t.BTW, t.Username));
        }

        protected override BLL.Model.User.User ReadByID(int id)
        {
            return DT.SingleOrDefault(x => x.UserID == id);
        }

        protected override void UpdateObject(BLL.Model.User.User left, BLL.Model.User.User right, bool replaceID)
        {
            if (replaceID) left.UserID = right.UserID;
            left.Lastname = right.Lastname;
            left.Firstname = right.Firstname;
            left.Phonenumber = right.Phonenumber;
            left.Street = right.Street;
            left.PostalCode = right.PostalCode;
            left.City = right.City;
            left.Country = right.Country;
            left.BTW = right.BTW;
            left.Username = right.Username;
            
        }

        protected override IEnumerable<BLL.Model.User.User> ApplyOrdering(IEnumerable<BLL.Model.User.User> query, IDictionary<Func<BLL.Model.User.User, object>, Enum.Ordering> columns)
        {
            return OrderHelper.ApplyOrdering<BLL.Model.User.User, object>(query, columns, user => user.UserID);
        }

        protected BLL.Model.User.User Create(string lname, string fname, string phone, string street, string postalcode, string city, string country, string btw, string uname)
        {
            return new BLL.Model.User.User()
            {
                Lastname = lname,
                Firstname = fname,
                Phonenumber = phone,
                Street = street,
                PostalCode = postalcode,
                City = city,
                Country = country,
                BTW = btw,
                Username = uname
            };
        }

        internal BLL.Model.User.User ReadUser(int userID)
        {
            return (from user in DT
                   where user.UserID == userID
                   select user).FirstOrDefault();
        }

        internal BLL.Model.User.User ReadUserFromDatabase(string username, string password)
        {
            return (from user in DT
                    where user.Username == username && user.Password == password
                    select user).FirstOrDefault();
        }
    }
}